﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Hammock;
using Hammock.Authentication.OAuth;
using Newtonsoft.Json.Linq;
using WeiboPlus.Service;
using WeiboPlus.Models;

namespace WeiboPlus.Sina
{
    public class SinaUserService : UserServiceBase
    {
        private const string GET_SUGGESTION_USER = "";

        protected override void Initialize()
        {
            GET_CURRENT_USER = "/2/users/show.json";
            GET_USER = "/2/users/show.json";
            FOLLOW_USER = "/2/friendships/create.json";
            UNFOLLOW_USER = "/2/friendships/destroy.json";
            FRIENDSHIP = "/2/friendships/show.json";
            //GET_USER_LIST = "/api/user/infos?format=json";
            //GET_FANS = "/api/friends/fanlist?format=json";
            //GET_FANS_LITE = "/api/friends/fanlist_s?format=json";
            //GET_IDOLS = "/api/friends/idollist?format=json";
            //GET_IDOLS_LITE = "/api/friends/idollist_s?format=json";
            GET_USER_IDOLS = "/2/friendships/friends.json";
            GET_USER_FANS = "/2/friendships/followers.json";
            SEARCH_USER = "/2/search/suggestions/users.json ";
        }

        protected override string[] GetParamtersList(SNSType type)
        {
            string[] list;
            switch (type)
            {
                case SNSType.SingleUser:
                    list = new string[] { 
                      SNSParametersConstants.SCREEN_NAME
                    };
                    break;
                case SNSType.UserFriends:
                    list = new string[] { 
                        SNSParametersConstants.UID,
                        SNSParametersConstants.CURSOR ,
                        SNSParametersConstants.COUNT
                    };
                    break;
                case SNSType.UserFollowers:
                    list = new string[] { 
                        SNSParametersConstants.UID,
                        SNSParametersConstants.CURSOR ,
                        SNSParametersConstants.COUNT
                    };
                    break;
                case SNSType.HotPeople:
                    return new string[]
                    { 
                        
                    };
                case SNSType.FriendShip:
                    return new string[]
                    { 
                        SNSParametersConstants.TARGET_ID,
                        SNSParametersConstants.SOURCE_ID
                    };
                case SNSType.Follow:
                    return new string[]
                    { 
                        SNSParametersConstants.USER_ID
                    };

                case SNSType.UnFollow:
                    return new string[]
                    { 
                        SNSParametersConstants.USER_ID
                    };

                case SNSType.SuggestionPeoples:
                    list = new string[] { 
                        //SNSParametersConstants.COUNT,
                        //SNSParametersConstants.BASE_APP
                    };
                    break;
                case SNSType.SearchUser:
                    list = new string[] { 
                        SNSParametersConstants.COUNT,
                        SNSParametersConstants.Q
                    };
                    break;
                default:
                    list = new string[] { };
                    break;
            }
            return list;
        }

        protected override System.Collections.Generic.IList<SNSUser> Mapping(string res, SNSResult result)
        {
            JObject o = JObject.Parse(res);

            List<SNSUser> users = o.SelectToken("users").Select(
                s => Factory.GetMapping<JToken, SNSUser>().Map(s)
                ).ToList();

            if (o.SelectToken("next_cursor") != null)
                result.PagingInfo = new SNSPagingInfo() { Cursor = (int)o.SelectToken("next_cursor"), HasNext = (int)o.SelectToken("next_cursor") == 0 ? false : true };
            return users;
        }

        protected override System.Collections.Generic.IList<T1> Mapping<T1>(string res, SNSResult result)
        {
            if (res.StartsWith("["))
            {
                res = "{\"users\":" + res + "}"; 
            };
            JObject o = JObject.Parse(res);

            List<T1> users = o.SelectToken("users").Select(
                s => Factory.GetMapping<JToken, T1>().Map(s)
                ).ToList();

            if (o.SelectToken("next_cursor") != null)
                result.PagingInfo = new SNSPagingInfo() { Cursor = (int)o.SelectToken("next_cursor"), HasNext = (int)o.SelectToken("next_cursor") == 0 ? false : true };
            return users;
        }

        protected override SNSUser MappingSingle(string res, SNSResult result)
        {
            JObject o = JObject.Parse(res);

            return Factory.GetMapping<JToken, SNSUser>().Map(o);
        }

        protected override T MappingSingle<T>(string res, SNSResult result)
        {
            JObject o = JObject.Parse(res);

            return Factory.GetMapping<JToken, T>().Map(o);
        }

        protected override int ValidateResponse(RestResponse res, out string msg)
        {
            if (res.Content.StartsWith("<"))
            {
                msg = res.Content;
                return 0;
            }

            if (string.IsNullOrEmpty(res.Content))
            {
                msg = "no data";
                return 99;
            }

            if (res.Content.Contains("error"))
            {
                msg = res.Content;
                //TO-DO HANDLE ERROR
                return 0;
            }
            msg = "ok";

            return 1;
        }

        public override void Follow(SNSUser user, Action<SNSUser, SNSResult> action)
        {
            SNSRequest request = new SNSRequest() { Type = SNSType.Follow, WebMethod = Hammock.Web.WebMethod.Post };

            request.Parameters.Add(new SNSParameter(SNSParametersConstants.UID, user.Id + ""));
            //request.Parameters.Add(new SNSParameter(SNSParametersConstants.NAME, user.AccountName + ""));
            //request.Parameters.Add(new SNSParameter(SNSParametersConstants.CLIENT_IP, "127.0.0.1"));

            //var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => true;

            PerformRequest(action, request);
        }

        public override void Unfollow(SNSUser user, Action<SNSUser, SNSResult> action)
        {
            //base.Unfollow(user, action);

            SNSRequest request = new SNSRequest() { Type = SNSType.Follow, WebMethod = Hammock.Web.WebMethod.Post };

            request.Parameters.Add(new SNSParameter(SNSParametersConstants.UID, user.Id + ""));
            //request.Parameters.Add(new SNSParameter(SNSParametersConstants.NAME, user.AccountName + ""));
            //request.Parameters.Add(new SNSParameter(SNSParametersConstants.CLIENT_IP, "127.0.0.1"));

            //var pList = GetParamtersList(request.Type);
            request.Predicate = (p) => true;

            PerformRequest(action, request);
        }

        public override void GetUser(SNSRequest snsRequest, Action<SNSUser, SNSResult> action)
        {
            if (snsRequest.Type == SNSType.CurrentUser)
            {
                snsRequest.Parameters.Add(new SNSParameter("uid", Account.UserName));
                snsRequest.Predicate = s => true; 
            }
            else
            {
                var pList = GetParamtersList(snsRequest.Type);
                snsRequest.Predicate = (p) => pList.Contains(p.Name);
            }
            
            PerformRequest(action, snsRequest);
        }

        public override void SearchUser(SNSRequest snsRequest, Action<IList<SNSUser>, SNSResult> action)
        {
            base.SearchUser(snsRequest, action);
            //var key = snsRequest.Parameters.FirstOrDefault(p => p.Name == SNSParametersConstants.KEYWORD);

        }
    }
}
